/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.ext.echarts.builder;

import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.entities.beans.table.TableField;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.type.EntityType;
import cn.easyplatform.web.ext.cmez.CMeditor;
import cn.easyplatform.web.ext.echarts.ECharts;
import cn.easyplatform.web.ext.echarts.lib.Legend;
import cn.easyplatform.web.ext.echarts.lib.Option;
import cn.easyplatform.web.ext.echarts.lib.Title;
import cn.easyplatform.web.ext.echarts.stuido.EchartsCallback;
import cn.easyplatform.web.ext.echarts.util.ChartType;
import cn.easyplatform.web.ext.echarts.util.GsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.*;
import org.zkoss.zul.event.PagingEvent;
import org.zkoss.zul.event.ZulEvents;

import java.util.*;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class EChartsBuilderController extends SelectorComposer<Component>
        implements EventListener<Event> {

    @Wire("div#themes")
    private Div themes;

    @Wire("echarts#echarts")
    private ECharts target;

    @Wire("cmeditor#editor")
    private CMeditor editor;

    @Wire("cmeditor#mcEditor")
    private CMeditor mcEditor;

    @Wire("include#templates")
    private Include templates;

    @Wire("bandbox#table")
    private Bandbox table;

    @Wire("bandbox#dbId")
    private Bandbox dbId;

    @Wire("textbox#query")
    private Textbox query;

    @Wire("textbox#filter")
    private Textbox filter;

    @Wire("checkbox#immediate")
    private Checkbox immediate;

    @Wire("label#label_sql_example")
    private Label sql_example;

    @Wire("button#table_show")
    private Button showTable;

    @Wire("textbox#titleContent")
    private Textbox titleContent;

    @Wire("radiogroup#titleSite")
    private Radiogroup titleSite;

    @Wire("radiogroup#legendSite")
    private Radiogroup legendSite;

    @Wire("checkbox#legendShow")
    private Checkbox legendShow;

    @Wire("checkbox#titleShow")
    private Checkbox titleShow;

    @Wire("div#seriesType")
    private Div seriesType;

    /*@Wire("radiogroup#radiogroup_createtype")
    private Radiogroup radiogroup_createtype;*/

    private String tableId;

    private ECharts source;

    private Collection<TemplateUnit> items;

    private EchartsCallback callback;

    private Window tebleEntityWin;

    private Window tableShowWin;

    private boolean xAxisSign;

    private boolean yAxisSign;

    private boolean keyValueSign;

    private Title title;

    private Legend legend;

    private Map<String,List> conditionMap;

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        comp.addEventListener(Events.ON_CLOSE,this);
        source = (ECharts) Executions.getCurrent().getArg().get("charts");
        callback = (EchartsCallback) Executions.getCurrent().getArg().get("event");
        tableId  = (String) Executions.getCurrent().getArg().get("tableId");
        table.addEventListener(Events.ON_CHANGE, this);
        table.addEventListener(Events.ON_OPEN, this);
        table.addEventListener(Events.ON_OK, this);
        table.getNextSibling().addEventListener(Events.ON_CLICK, this);
        titleContent.addEventListener(Events.ON_CHANGE,this);
        titleSite.addEventListener(Events.ON_CHECK,this);
        legendSite.addEventListener(Events.ON_CHECK,this);
        legendShow.addEventListener(Events.ON_CHECK,this);
        titleShow.addEventListener(Events.ON_CHECK,this);
        dbId.addEventListener(Events.ON_CHANGE, this);
        dbId.addEventListener(Events.ON_OPEN, this);
        dbId.addEventListener(Events.ON_OK, this);
        if(!Strings.isBlank(tableId))
            table.setValue(tableId);
        dbId.setValue(source.getDbId());
        query.setValue((String) source.getQuery());
        filter.setValue(source.getFilter());
        immediate.setChecked(source.isImmediate());
        String type = Strings.isBlank(source.getType()) ? ChartType.bar.name() : source.getType();
        target.setTheme(source.getTheme());
        target.setTemplate(source.getTemplate());
        target.setType(type);
        target.setOption(source.getOption());
        /*target.setCreateType(radiogroup_createtype.getSelectedItem().getValue());*/
        IEChartsBuilder builder = EChartsBuilderFactory.createBuilder(target.getType());
        TemplateUnit item = builder.getTemplate(source.getTemplate());
        Option option = item.getOption() == null ? new Option() : GsonUtil.fromJson(item.getOption());
        items = builder.getTemplates();
        conditionMap = builder.getCondition();
        createTypeChange();
        chackParm(false,option);
        editor.setValue(builder.build(target.getOption(), builder.getTemplate(target.getTemplate()), true));
        editor.formatAll();
        templates.setSrc("~./js/echarts/builder/" + type + ".zul");
    }

    public Collection<TemplateUnit> getTemplates() {
        return items;
    }

    @Listen("onChange=textbox;onChange=intbox;onChange=combobox;onCheck=checkbox")
    public void onPropertyChanged(Event evt) {
        Component c = evt.getTarget();
    }

    @Listen("onChange=#editor")
    public void onEditorChanged(Event evt) {
        if (!Strings.isBlank((String) editor.getValue())){
            Option option = GsonUtil.fromJson((String) editor.getValue());
            redraw(option);
            createTypeChange();
        }
    }

    @Listen("onClick=#confirm")
    public void onConfirm(Event evt) {
        /*source.setOption(target.getOption());
        source.setTheme(target.getTheme());
        source.setType(target.getType());
        source.setTemplate(target.getTemplate());
        source.setQuery(query.getValue());
        source.setFilter(filter.getValue());
        source.setDbId(dbId.getValue());
        source.setImmediate(immediate.isChecked());*/

        //抛出数据交由外部渲染
        Map<String,Object> eChartsData = new HashMap();
        eChartsData.put("option",target.getOption());
        eChartsData.put("theme",target.getTheme());
        eChartsData.put("type",target.getType());
        eChartsData.put("template",target.getTemplate());
        eChartsData.put("query",query.getValue());
        eChartsData.put("filter",filter.getValue());
        eChartsData.put("dbId",dbId.getValue());
        eChartsData.put("immediate",immediate.isChecked());
        evt.getTarget().setAttribute("eChartsData",eChartsData);

        evt.getTarget().getRoot().detach();
        try {
            callback.onEvent(evt);
        } catch (Exception e) {
        }
    }

    @Listen("onClick=a")
    public void onSelectItem(Event evt) {
        Image image = (Image) evt.getTarget().query("image");
        if (image == null) {
            A a = (A) evt.getTarget();
            String name = StringUtils.substringBefore(StringUtils.substringAfterLast(a.getImage(), "/"), ".");
            target.setTheme(name);
            a.setSclass("selected");
            for (Component c : a.getParent().getChildren()) {
                if (c != a)
                    ((A) c).setSclass("");
            }
        } else {
            String name = StringUtils.substringBefore(StringUtils.substringAfterLast(image.getSrc(), "/"), ".");
            if (!name.equals(target.getType())) {
                for (ChartType type : ChartType.values()) {
                    if (type.name().equals(name)) {
                        IEChartsBuilder builder = EChartsBuilderFactory.createBuilder(type.name());
                        items = builder.getTemplates();
                        TemplateUnit item = null;
                        Option option = null;
                        if (name.equals(source.getType())) {
                            item = builder.getTemplate(source.getTemplate());
                            option = source.getOption();
                        } else {
                            item = items.iterator().next();
                            option = item.getOption() == null ? new Option() : GsonUtil.fromJson(item.getOption());
                        }
                        target.setType(type.name());
                        target.setTemplate(item.getName());
                        editor.setValue(builder.build(option, item, true));
                        target.clearInit();
                        target.setOption(option);
                        editor.formatAll();
                        chackParm(true,option);
                        createTypeChange();
                        templates.setSrc("~./js/echarts/builder/" + type + ".zul");
                        break;
                    }
                }
            }
        }
    }

    public void onViewTemplate(Component c, String name) {
        TemplateUnit item = EChartsBuilderFactory.createBuilder(target.getType()).getTemplate(name);
        mcEditor.setValue(item.getOption());
        ((Popup) mcEditor.getParent()).open(c, "start_before");
    }

    public void onDataTemplate(Component c, String name) {
        TemplateUnit item = EChartsBuilderFactory.createBuilder(target.getType()).getTemplate(name);
        mcEditor.setValue(item.getJson());
        ((Popup) mcEditor.getParent()).open(c, "start_before");
    }

    public void onApplyTemplate(Component c, String name) {
        IEChartsBuilder builder = EChartsBuilderFactory.createBuilder(target.getType());
        TemplateUnit item = builder.getTemplate(name);
        Option option = item.getOption() == null ? new Option() : GsonUtil.fromJson(item.getOption());
        editor.setValue(builder.build(option, item, false));
        target.clearInit();
        target.setOption(option);
        target.setTemplate(item.getName());
        editor.formatAll();
        chackParm(true,option);
        createTypeChange();
    }

    public void createTypeChange (){
        seriesType.getChildren().clear();
        if(target.getType().equals(ChartType.bar.name())
                || target.getType().equals(ChartType.line.name())) {
            if (target.getOption().getSeries() instanceof List) {
                List serieslist = (List) target.getOption().getSeries();
                for (int i = 0; i < serieslist.size(); i++) {
                    Map<String, Object> serie = (Map<String, Object>) serieslist.get(i);
                    Label label = new Label("Series"+i);
                    createRadio(serie,label,target.getTemplate());
                }
            } else if(target.getOption().getBaseOption()!=null &&
                    target.getOption().getBaseOption().getSeries() instanceof List){
                List serieslist = (List) target.getOption().getBaseOption().getSeries();
                for (int i = 0; i < serieslist.size(); i++) {
                    Map<String, Object> serie = (Map<String, Object>) serieslist.get(i);
                    Label label = new Label("Series"+i);
                    createRadio(serie,label,target.getTemplate());
                }
            } else {
                Map<String, Object> serie;
                if(target.getOption().getSeries()==null
                        && target.getOption().getBaseOption()!=null){
                    serie = (Map<String, Object>)target.getOption().getBaseOption().getSeries();
                }else {
                    serie = (Map<String, Object>)target.getOption().getSeries();
                }
                Label label = new Label("Series");
                createRadio(serie ,label,target.getTemplate());
            }
        }
    }

    public void createRadio(Map<String, Object> serie,Label label,String name){
        Radiogroup radiogroup = new Radiogroup();
        Hlayout hlayout = new Hlayout();
        Radio bar = new Radio();
        bar.setLabel(ChartType.bar.name());
        Radio line = new Radio();
        line.setLabel(ChartType.line.name());
        hlayout.appendChild(label);
        hlayout.appendChild(bar);
        hlayout.appendChild(line);
        List list = conditionMap.get("unusePie");
        if (!list.contains(name)) {
            Radio pie = new Radio();
            pie.setLabel(ChartType.pie.name());
            hlayout.appendChild(pie);
        }
        hlayout.setParent(radiogroup);
        if(serie.get("type").equals(ChartType.bar.name())){
            bar.setSelected(true);
        } else if(serie.get("type").equals(ChartType.line.name())){
            line.setSelected(true);
        } else{
            if(radiogroup.getItems().size()>2) {
                radiogroup.setSelectedIndex(2);
            }
        }

        radiogroup.addEventListener(Events.ON_CHECK, new EventListener<Event>() {
            @Override
            public void onEvent(Event event) throws Exception {
                String str = radiogroup.getSelectedItem().getLabel();
                serie.put("type",str);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                redraw(target.getOption());
            }
        });
        radiogroup.setParent(seriesType);
    }

    public void redraw(Option option){
        if (option==null)
            return;
        try {
            IEChartsBuilder builder = EChartsBuilderFactory.createBuilder(target.getType());
            builder.build(option, builder.getTemplate(target.getTemplate()), false);
            target.clearInit();
            target.setOption(option);
        } catch (Exception e) {
            e.printStackTrace();
            if (e.getMessage() != null) {
                if (e.getMessage().indexOf(":") > 0)
                    Clients.wrongValue(editor, StringUtils.substringAfter(e.getMessage(), ":"));
                else
                    Clients.wrongValue(editor, e.getMessage());
            }
        }
    }

    //识别Option内数据，判断开放的变量是否包含x轴、y轴,是否有标题和图例
    private void chackParm(boolean type,Option option){
        StringBuffer sb = new StringBuffer();
        sb.append("select ");
        //sequence原用作用户可修改图表开放的变量，现不可修改但仍保留该设计
        Set sequence = source.getSequence();
        //当序列集合无数据时，读取Option内容
        Map<String, Object> xAxis = null;
        Map<String, Object> yAxis = null;
        if(sequence.isEmpty()){
            if (option.getxAxis() != null) {
                if (option.getxAxis() instanceof List)
                    xAxis = (Map<String, Object>) ((List) option.getxAxis()).get(0);
                else
                    xAxis = (Map<String, Object>) option.getxAxis();
                if ("data".equals(xAxis.get("data"))) {
                    sequence.add("xAxis");
                }
            }
            if (option.getyAxis() != null) {
                if (option.getyAxis() instanceof List)
                    yAxis = (Map<String, Object>) ((List) option.getyAxis()).get(0);
                else
                    yAxis = (Map<String, Object>) option.getyAxis();
                if ("data".equals(yAxis.get("data"))) {
                    sequence.add("yAxis");
                }
            }
            sequence.add("value");
        }
        //序列集合有数据时延续已有数据
        if(sequence.contains("xAxis")){
            xAxisSign = true;
            sb.append("xAxis,");
            /*if (option.getxAxis() != null) {
                if (option.getxAxis() instanceof List)
                    xAxis = (Map<String, Object>) ((List) option.getxAxis()).get(0);
                else xAxis = (Map<String, Object>) option.getxAxis();
                if (!"data".equals(xAxis.get("data"))) {
                    xAxis.put("data","data");//用户标记为变量，则将该参数修改为data识别替换
                }
            }*/
        }else{
            xAxisSign = false;
        }
        if(sequence.contains("yAxis")){
            yAxisSign = true;
            sb.append("yAxis,");
           /* if (option.getyAxis() != null) {
                if (option.getyAxis() instanceof List)
                    yAxis = (Map<String, Object>) ((List) option.getyAxis()).get(0);
                else yAxis = (Map<String, Object>) option.getyAxis();
                if (!"data".equals(yAxis.get("data"))) {
                    yAxis.put("data","data");//用户标记为变量，则将该参数修改为data识别替换
                }
            }*/
        }else{
            yAxisSign = false;
        }
        if(sequence.contains("value")){
            keyValueSign = true;
            sb.append("kind,value");
        }else{
            keyValueSign = false;
        }
        sb.append(" from table");
        sql_example.setValue(sb.toString());
        //识别标题内容
        if(option.getTitle()!=null){
            title = (Title) option.getTitle();
            titleContent.setValue(title.getText());
            titleShow.setDisabled(false);
            titleShow.setChecked(true);
            for(Radio radio : titleSite.getItems()) {
                radio.setDisabled(false);
                if (title.getLeft() != null && radio.getLabel().equals(title.getLeft())) {
                    radio.setSelected(true);
                }
            }
           if(titleSite.getSelectedItem()==null) {
               titleSite.setSelectedIndex(0);
           }

        }else{
            title = new Title();
            titleContent.setValue("");
            titleShow.setChecked(false);
            titleShow.setDisabled(true);
            titleSite.setSelectedIndex(-1);
            for(Radio radio : titleSite.getItems()) {
                radio.setDisabled(true);
            }
        }
        //识别图例内容,若无图例则添加默认图例
        if(option.getLegend()!=null ){
            legend = option.getLegend();
            legendShow.setChecked(true);
            for(Radio radio : legendSite.getItems()) {
                radio.setDisabled(false);
                if (legend.getLeft() != null && radio.getLabel().equals(legend.getLeft())) {
                    radio.setSelected(true);
                }
            }
            if(legendSite.getSelectedItem()==null) {
                legendSite.setSelectedIndex(1);
            }
        }else if(option.getBaseOption()!=null&&option.getBaseOption().getLegend()!=null){
            legend = option.getBaseOption().getLegend();
            legendShow.setChecked(true);
        }else{
            legend = new Legend();
            List<String> list = new ArrayList<>();
            list.add("default");
            legend.setData(list);
            legend.setShow(false);
            Map<String, Object> serie = null;
            if (option.getSeries() instanceof Map) {
                serie = (Map<String, Object>) option.getSeries();
            } else if (option.getSeries() instanceof List) {
                serie = (Map<String, Object>) ((List) option.getSeries()).get(0);
            }
            serie.put("name","default");
            legendShow.setChecked(false);
            legendSite.setSelectedIndex(-1);
            for(Radio radio : legendSite.getItems()) {
                radio.setDisabled(true);
            }
        }

        if(type) {
            query.setValue("");
            filter.setValue("");
        }
    }

    @Override
    public void onEvent(Event evt) throws Exception {
        Component c = evt.getTarget();
        if (evt.getName().equals(Events.ON_OPEN)) {
            if (evt instanceof OpenEvent){
                ((Bandbox) c).setValue(((OpenEvent)evt).getValue()+"");
            }
            new TebleEntityView(c.getPage(),((Bandbox) c).getValue());
        }else if(evt.getName().equals(Events.ON_CLOSE)){
            if(tebleEntityWin!=null) {
                tebleEntityWin.detach();
            }
            if(tableShowWin!=null) {
                tableShowWin.detach();
            }
        }else if(evt.getTarget() == showTable){
            if(!Strings.isBlank(table.getValue())) {
                TableBean tableBean = callback.getTableValue(table.getValue());
                if(tableBean!=null) {
                    if(tableShowWin!=null) {
                        tableShowWin.detach();
                    }
                    new TableShowView(c.getPage(), tableBean);
                }
            }
        }else if(evt.getTarget() == titleContent){
            if(!Strings.isBlank(titleContent.getValue())){
                title.setText(titleContent.getValue());
                target.getOption().setTitle(title);
                titleShow.setDisabled(false);
                titleShow.setChecked(true);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                for(Radio radio : titleSite.getItems()) {
                    radio.setDisabled(false);
                }
                titleSite.setSelectedIndex(-1);
                redraw(target.getOption());
            }
        }else if(evt.getTarget() instanceof Radio){
            if(((Radio) evt.getTarget()).getRadiogroup().equals(titleSite)
                    && titleSite.getSelectedItem()!=null) {
                title.setLeft(titleSite.getSelectedItem().getLabel());
                target.getOption().setTitle(title);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                redraw(target.getOption());
            }
            if(((Radio) evt.getTarget()).getRadiogroup().equals(legendSite)
                    && legendSite.getSelectedItem()!=null){
                legend.setLeft(legendSite.getSelectedItem().getLabel());
                target.getOption().setLegend(legend);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                redraw(target.getOption());
            }
        } else if(evt.getTarget() == legendShow){
            if(legendShow.isChecked()){
                legend.setShow(true);
                legend.setLeft("center");
                legendSite.setSelectedIndex(1);
                target.getOption().setLegend(legend);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                for(Radio radio : legendSite.getItems()) {
                    radio.setDisabled(false);
                }
                legendSite.setSelectedIndex(1);
                redraw(target.getOption());
            }else{
                legend.setShow(false);
                target.getOption().setLegend(legend);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                for(Radio radio : legendSite.getItems()) {
                    radio.setDisabled(true);
                }
                legendSite.setSelectedIndex(-1);
                redraw(target.getOption());
            }
        } else if(evt.getTarget() == titleShow){
            if(titleShow.isChecked()){
                title.setShow(true);
                title.setLeft("left");
                target.getOption().setTitle(title);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                for(Radio radio : titleSite.getItems()) {
                    radio.setDisabled(false);
                }
                titleSite.setSelectedIndex(0);
                redraw(target.getOption());
            }else{
                title.setShow(false);
                target.getOption().setTitle(title);
                editor.setValue(GsonUtil.format(target.getOption()));
                editor.formatAll();
                for(Radio radio : legendSite.getItems()) {
                    radio.setDisabled(true);
                }
                titleSite.setSelectedIndex(-1);
                redraw(target.getOption());
            }
        }


    }


    //所有数据表查询内部类
    private class TebleEntityView implements EventListener<Event> {

        private String tableName;

        private Bandbox searchbox;

        private Grid grid;

        private Paging paging;



        public TebleEntityView(Page page,String tableName) {
            this.tableName = tableName;
            tebleEntityWin = new Window();
            tebleEntityWin.setTitle(Labels.getLabel("echarts.entity.tableField"));
            tebleEntityWin.setClosable(true);
            tebleEntityWin.setPage(page);
            tebleEntityWin.setMaximizable(true);
            tebleEntityWin.setHeight("500px");
            tebleEntityWin.setWidth("850px");
            tebleEntityWin.setSizable(true);
            tebleEntityWin.setFocus(true);
            Borderlayout layout = new Borderlayout();
            Center body = new Center();
            body.setHflex("1");
            body.setVflex("1");
            body.setBorder("none");
            body.setParent(layout);
            tebleEntityWin.appendChild(layout);
            createHeader(layout);
            createContent(body);
            createFooter(layout);
            tebleEntityWin.setPosition("top,center");
            tebleEntityWin.doOverlapped();

        }

        protected void createHeader(Component parent) {
            // 搜索栏
            North searchbar = new North();
            searchbar.setBorder("none");
            searchbar.setSize("30px");
            searchbar.setHflex("1");
            Div bar = new Div();
            Label label = new Label(Labels.getLabel("echarts.search.key") + ":");
            label.setParent(bar);
            searchbox = new Bandbox();
            searchbox.setPlaceholder(Labels.getLabel("echarts.search.placeholder"));
            searchbox.addEventListener(Events.ON_OK, this);
            searchbox.addEventListener(Events.ON_OPEN, this);
            searchbox.setParent(bar);
            bar.setParent(searchbar);
            searchbar.setParent(parent);
        }

        protected void createContent(Component parent) {
            // 内容
            grid = new Grid();
            grid.setHflex("1");
            grid.setVflex("1");
            Columns columns = new Columns();
            columns.setSizable(true);
            Column column = new Column(Labels.getLabel("echarts.entity.id"));
            column.setWidth("200px");
            column.setParent(columns);

            column = new Column(Labels.getLabel("echarts.entity.name"));
            column.setWidth("200px");
            column.setParent(columns);

            column = new Column(Labels.getLabel("echarts.entity.type"));
            column.setWidth("60px");
            column.setParent(columns);

            column = new Column(Labels.getLabel("echarts.entity.desp"));
            column.setHflex("1");
            column.setParent(columns);

            columns.setParent(grid);
            grid.appendChild(new Rows());
            grid.setParent(parent);
        }

        protected void createFooter(Component parent) {
            paging = new Paging();
            paging.setPageSize(20);
            paging.setDetailed(true);
            paging.addEventListener(ZulEvents.ON_PAGING, this);
            South south = new South();
            south.setBorder("none");
            south.setHflex("1");
            south.setSize("30px");
            south.appendChild(paging);
            south.setParent(parent);
            Map result = callback.getTable(EntityType.TABLE.getName(),
                    paging,tableName);
            paging.setTotalSize((int)result.get("totalSize"));
            redraw((List) result.get("entities"));
        }

        private void redraw(List<List> data) {
            for (List vo : data) {
                Row row = new Row();
                row.setSclass("echarts-link");
                row.setValue(vo);
                row.appendChild(new Label((String)vo.get(0)));
                row.appendChild(new Label((String)vo.get(1)));
                row.appendChild(new Label((String)vo.get(2)));
                row.appendChild(new Label((String)vo.get(3)));
                row.setParent(grid.getRows());
                row.addEventListener(Events.ON_DOUBLE_CLICK, this);
            }
        }

        @Override
        public void onEvent(Event event) throws Exception {
            if (event.getName().equals(ZulEvents.ON_PAGING)) {
                PagingEvent pe = (PagingEvent) event;
                int pageNo = pe.getActivePage() + 1;
                List data = callback.getTablePaging(EntityType.TABLE.getName(),
                        paging,searchbox.getValue().trim(),pageNo);
                grid.getRows().getChildren().clear();
                redraw(data);
            } else if (event.getTarget() == searchbox) {
                String val = null;
                if (event instanceof OpenEvent) {
                    OpenEvent evt = (OpenEvent) event;
                    val = (String) evt.getValue();
                    searchbox.setValue(val);
                } else
                    val = searchbox.getValue();
                Map result = callback.getTable(EntityType.TABLE.getName(),
                        paging,val.trim());
                paging.setTotalSize((int)result.get("totalSize"));
                grid.getRows().getChildren().clear();
                redraw((List) result.get("entities"));
            } else if (event.getTarget() instanceof Row) {
                Row row = (Row) event.getTarget();
                List vo = row.getValue();
                TableBean tableBean = callback.getTableValue((String) vo.get(0));
                if(tableBean!=null) {
                    if(tableShowWin!=null) {
                        tableShowWin.detach();
                    }
                    new TableShowView(row.getPage(), tableBean);
                }
                table.setValue((String) vo.get(0));
            }
        }
    }

    //数据表详细字段内部类
    private class TableShowView implements EventListener<Event> {

        private TableBean tableBean;

        private Listbox listbox;

        private Paging paging;

        private Button closeBtn;

        private Button confirmBtn;

        private Radiogroup radiogroup;

        public TableShowView(Page page,TableBean tableBean) {

            this.tableBean = tableBean;
            tableShowWin = new Window();
            tableShowWin.setTitle(Labels.getLabel("echarts.entity.table"));
            tableShowWin.setClosable(true);
            tableShowWin.setPage(page);
            tableShowWin.setMaximizable(true);
            tableShowWin.setHeight("500px");
            tableShowWin.setWidth("850px");
            tableShowWin.setSizable(true);
            tableShowWin.setFocus(true);
            Borderlayout layout = new Borderlayout();
            Center body = new Center();
            body.setHflex("1");
            body.setVflex("1");
            body.setBorder("none");
            body.setParent(layout);
            tableShowWin.appendChild(layout);
            createHeader(layout);
            createContent(body);
            createFooter(layout);
            tableShowWin.setPosition("top,center");
            tableShowWin.doOverlapped();

        }

        protected void createHeader(Component parent) {
            North searchbar = new North();
            searchbar.setBorder("none");
            searchbar.setSize("30px");
            searchbar.setHflex("1");
            Div bar = new Div();
            Label label = new Label(Labels.getLabel("echarts.entity.tableName")
                    + " : "+tableBean.getId());
            label.setParent(bar);
            bar.setParent(searchbar);
            searchbar.setParent(parent);
        }


        protected void createContent(Component parent) {
            // 内容
            Vlayout bar = new Vlayout();
            Hlayout lay = new Hlayout();
            lay.setHflex("1");
            Label lab = new Label(Labels.getLabel("echarts.sql.rule")+" :");
            lab.setParent(lay);
            radiogroup = new Radiogroup();
            radiogroup.appendItem(Labels.getLabel("echarts.entity.usetotal"),"0");
            radiogroup.appendItem(Labels.getLabel("echarts.entity.usecount"),"1");
            radiogroup.setSelectedIndex(0);
            radiogroup.setParent(lay);
            lay.setParent(bar);
            Label label = new Label(Labels.getLabel("echarts.entity.TableEchField")+" :");
            label.setParent(bar);
            listbox = new Listbox();
            listbox.setHflex("1");
            listbox.setVflex("1");
            listbox.setCheckmark(true);
            listbox.setMultiple(true);
            listbox.setStyle("border:none");
            Listhead listhead = new Listhead();
            listhead.setSizable(true);
            listhead.setParent(listbox);
            Listheader listheader = new Listheader();
            listheader.setLabel(Labels.getLabel("echarts.entity.name"));
            listheader.setHflex("1");
            listheader.setParent(listhead);
            listheader = new Listheader();
            listheader.setLabel(Labels.getLabel("echarts.entity.type"));
            listheader.setHflex("1");
            listheader.setParent(listhead);
            listheader = new Listheader();
            listheader.setLabel(Labels.getLabel("echarts.entity.desp"));
            listheader.setHflex("1");
            listheader.setParent(listhead);
            listheader = new Listheader();
            listheader.setLabel(Labels.getLabel("echarts.entity.parmType"));
            listheader.setHflex("1");
            listheader.setParent(listhead);
            listbox.setParent(bar);
            bar.setParent(parent);
            redraw(tableBean);
        }

        private void redraw(TableBean tableBean) {
            for (TableField vo : tableBean.getFields()) {
                Listitem listitem = new Listitem();
                listitem.setValue(vo);
                Listcell nameListcell = new Listcell(vo.getName());
                listitem.appendChild(nameListcell);
                Listcell typeListcell = new Listcell(vo.getType().name());
                listitem.appendChild(typeListcell);
                Listcell despListcell = new Listcell(vo.getDescription());
                listitem.appendChild(despListcell);
                Listcell radiocell = new Listcell();
                Radiogroup radiogroup = new Radiogroup();
                if(xAxisSign){
                    radiogroup.appendItem(Labels.getLabel("echarts.view.xAxis"),"xAxis");
                }
                if(yAxisSign){
                    radiogroup.appendItem(Labels.getLabel("echarts.view.yAxis"),"yAxis");
                }
                if(keyValueSign){
                    radiogroup.appendItem(Labels.getLabel("echarts.view.key"),"key");
                    radiogroup.appendItem(Labels.getLabel("echarts.view.value"),"value");
                }
                radiogroup.addEventListener(Events.ON_CHECK, new EventListener<Event>() {
                    @Override
                    public void onEvent(Event event) throws Exception {
                        //该属性用来暂存echarts字段种类
                        vo.setOptionValue(radiogroup.getSelectedItem().getValue());
                    }
                });
                radiocell.appendChild(radiogroup);
                listitem.appendChild(radiocell);
                listitem.setParent(listbox);
            }
        }

        protected void createFooter(Component parent) {
            South south = new South();
            south.setBorder("none");
            south.setHflex("1");
            south.setSize("70px");
            Vlayout Vlayout = new Vlayout();
            Vlayout.setHflex("1");
            Vlayout.setVflex("1");
            paging = new Paging();
            paging.setPageSize(7);
            paging.setDetailed(true);
            paging.addEventListener(ZulEvents.ON_PAGING, this);
            paging.setTotalSize(tableBean.getFields().size());
            paging.setParent(Vlayout);
            Div buttonDiv = new Div();
            buttonDiv.setHflex("1");
            buttonDiv.setHeight("30px");
            buttonDiv.setStyle("text-align: center;");
            Vlayout.appendChild(buttonDiv);
            closeBtn = new Button(Labels.getLabel("echarts.entity.cancel"));
            closeBtn.setStyle("width: 100px");
            closeBtn.addEventListener(Events.ON_CLICK, this);
            buttonDiv.appendChild(closeBtn);
            confirmBtn = new Button(Labels.getLabel("echarts.entity.confirm"));
            confirmBtn.setStyle("margin-left: 100px;width: 100px");
            confirmBtn.addEventListener(Events.ON_CLICK, this);
            buttonDiv.appendChild(confirmBtn);
            south.appendChild(Vlayout);
            south.setParent(parent);

        }

        @Override
        public void onEvent(Event event) throws Exception {
            if (event.getTarget() == confirmBtn) {
                List<Listitem> list = listbox.getItems();
                Map parmmap = new HashMap();
                List<String> valuelist= new ArrayList();
                for (Listitem item : list) {
                    if (!item.isSelected())
                        continue;
                    if (item.getValue() != null) {
                        TableField field = item.getValue();
                        if(field.getOptionValue()!=null&&field.getOptionValue().equals("xAxis")){
                            parmmap.put("xAxis",field.getName());
                        }else if(field.getOptionValue()!=null&&field.getOptionValue().equals("yAxis")){
                            parmmap.put("yAxis",field.getName());
                        }else if(field.getOptionValue()!=null&&field.getOptionValue().equals("key")){
                            parmmap.put("key",field.getName());
                        }else if(field.getOptionValue()!=null&&field.getOptionValue().equals("value")){
                            valuelist.add(field.getName());
                        }
                    }
                }
                StringBuffer sqlsb = new StringBuffer();
                sqlsb.append("select ");
                if(!Strings.isBlank((String)parmmap.get("xAxis"))){
                    sqlsb.append("a."+parmmap.get("xAxis")+",");
                }
                if(!Strings.isBlank((String)parmmap.get("yAxis"))){
                    sqlsb.append("a."+parmmap.get("yAxis")+",");
                }
                if(!Strings.isBlank((String)parmmap.get("key"))){
                    sqlsb.append("a."+parmmap.get("key")+",");
                }
                if(radiogroup.getSelectedItem().getValue().equals("0")){
                    if(!valuelist.isEmpty()){
                        for(int i =0;i<valuelist.size();i++){
                            sqlsb.append("a."+valuelist.get(i));
                            if(i<valuelist.size()-1){
                                sqlsb.append(",");
                            }
                        }
                        sqlsb.append(" from "+tableBean.getId()+" a");
                    }
                }else{
                    if(!valuelist.isEmpty()){
                        for(int i =0;i<valuelist.size();i++){
                            sqlsb.append(valuelist.get(i)+"Table.count");
                            if(i<valuelist.size()-1){
                                sqlsb.append(",");
                            }
                        }
                        sqlsb.append(" from "+tableBean.getId()+" a");
                        for(int i =0;i<valuelist.size();i++){
                            sqlsb.append(" left join ( select "+valuelist.get(i)+",count(*) as count");
                            sqlsb.append(" from "+tableBean.getId()+" group by "+valuelist.get(i)+" ) "+valuelist.get(i)+"Table");
                            sqlsb.append(" on a."+valuelist.get(i)+"="+valuelist.get(i)+"Table."+valuelist.get(i));
                        }
                    }
                }
                query.setValue(sqlsb.toString());
                tableShowWin.detach();
                if(tebleEntityWin!=null) {
                    tebleEntityWin.detach();
                }
            } else if (event.getTarget() == closeBtn) {
                tableShowWin.detach();
            }
        }
    }
}

